using System;
using System.Collections.Generic;
using Survival.Services;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;


namespace Survival.Animals
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public partial class AnimalManager : DrawableGameComponent
    {
        SpriteBatch animalBatch;
        Dictionary<string, Texture2D> spriteDictionary;
        List<Animal> animalList;
        AnimalServices animalServices;
        IWorldQuery worldQueryService;
        IInputService inputService;
        IDebugTextService debugTextService;

        public IInputService InputService { get { return inputService; } }
        public List<Animal> AnimalList { get { return animalList; } }


        public AnimalManager(Game game)
            : base(game)
        {
            spriteDictionary = new Dictionary<string, Texture2D>();
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            animalBatch = new SpriteBatch(GraphicsDevice);
            animalList = new List<Animal>();
            worldQueryService = (IWorldQuery)Game.Services.GetService(typeof(IWorldQuery));
            inputService = (IInputService)Game.Services.GetService(typeof(IInputService));
            debugTextService = (IDebugTextService)Game.Services.GetService(typeof(IDebugTextService));
            animalServices = new AnimalServices(debugTextService, inputService, worldQueryService);

            CreateTestAnimals();
        }

        private void CreateTestAnimals()
        {
            AddAnimal(new Cow(new Vector2(400, 400), animalServices));
            AddAnimal(new Crow(new Vector2(600, 300), animalServices));
            AddAnimal(new Crow(new Vector2(200, 300), animalServices));
            AddAnimal(new Crow(new Vector2(100, 100), animalServices));
        }

        protected override void LoadContent()
        {
            spriteDictionary.Add("Cow",Game.Content.Load<Texture2D>("Cow"));
            spriteDictionary.Add("Crow", Game.Content.Load<Texture2D>("Crow"));
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            if (inputService.KeyPressed(Keys.C))
            {
                Vector2 offsetmouse = InputService.MousePositionVector + Vector2.One;
                AddAnimal(new Crow(offsetmouse, animalServices));
            }
            foreach (Animal animal in animalList)
            {
                animal.Update(gameTime);
            }
            base.Update(gameTime);
            
            Vector2 animalCountPosition = new Vector2(1,20);
            debugTextService.DrawString(new DrawableString("Animal Count: " + animalList.Count.ToString(), animalCountPosition));
            
        }

        public void AddAnimal(Animal animal)
        {
            animalList.Add(animal);
        }


        public override void Draw(GameTime gameTime)
        {
            Texture2D currentSprite;

            animalBatch.Begin();
            foreach (Animal animal in animalList)
            {
                spriteDictionary.TryGetValue(animal.SpriteName, out currentSprite);
                Vector2 spriteCenter = new Vector2(currentSprite.Bounds.Center.X,currentSprite.Bounds.Center.Y);
                animalBatch.Draw(currentSprite, animal.Position, null, Color.White, animal.Rotation, spriteCenter, 1f, SpriteEffects.None, 0);
            }
            animalBatch.End();
            base.Draw(gameTime);
        }
    }

    public class AnimalServices
    {
        private IWorldQuery worldQuery;
        private IInputService inputService;
        private IDebugTextService debugTextService;

        public IWorldQuery WorldQuery { get { return worldQuery; } }
        public IInputService InputService { get { return inputService; } }
        public IDebugTextService DebugTextSerivce { get { return debugTextService; } }

        public AnimalServices(IDebugTextService debugtext, IInputService input, IWorldQuery worldQuery)
        {
            debugTextService = debugtext;
            inputService = input;
            this.worldQuery = worldQuery;
        }
    }
}
